/*
Ramesh Marikhu <marikhu@yahoo.com>
Last Modified: 6th Feb 2009.
Version 0.1
*/
#ifndef IMAGEMANIP_H_
	#define IMAGEMANIP_H_

#include <stdexcept>
#include <cv.h>
#include <highgui.h>

class ImageManip
{
public:
    // Exception class for errors encountered by ImageManip
    class Exception : public std::runtime_error {
    public:
        Exception( const char *szMsg );
    };
	
	// Default parameters for Harris Feature points
	static const int iBlockSizeDefaultHarris = 3;
	static const int iMaskSizeDefaultHarris = 5;
	static const float fKappaDefaultHarris;
	static const int iMaxPixelValueDefaultHarris = 100;
	static const float fThresDefaultHarris;

	// ( 2 * iMaskSize + 1)^2 window for Non-maximal supression
	static const int iMaskSizeDefaultNMS = 4;

	// Default paramters for Log Transformation
	static const int iConstDefaultLog = 255;
	static const float fEpsDefaultLog;

	// Default Parameters for Canny edge 
	static const int iThresLowDefaultCanny = 40;
	static const int iThresHighDefaultCanny = 120;
	static const int iSobelMaskSizeDefaultCanny = 3;

	// Default Parameters for cvSmooth
	static const int iSmoothTypeDefaultSmooth = 2;	//CV_GAUSSIAN
	static const int iSize1DefaultSmooth = 3;
	static const int iSize2DefaultSmooth = 0;
	static const double dSigma1DefaultSmooth;
	static const double dSigma2DefaultSmooth;

	// Default enclosure level for highlightPtsOnImage()
	static const int iEnclosureLevelDefaultHighlight = 4;

	ImageManip();
	~ImageManip();

	void checkImage( IplImage* pImage );
	
	void computeHarrisFeaturePts( int iDepth );

	void scaleImage( int iDepth );	// This is IPL_DEPTH_32F image scaling for max value only.

	void scaleImage( int iMinValue, int iMaxValue );

	void getMinMax( float *fMinValue, float *fMaxValue );

	void supressBelowThreshold( float fThres );

	void performNonMaximalSupression();  

	void computeLogTransformation();

	void getCannyEdgeImage();

	void getSmoothImage();

	void getANDImage( IplImage* pImage );

	void getORImage( IplImage* pImage );

	void forceBinary( IplImage* pImage );

	IplImage* highlightPtsOnImage( IplImage* pImage );

	void dumpHarrisPts( const char *szFileName );
	
	/** Getters and Setters */
	void setImageSrc( IplImage* pImageSrc );

	IplImage* getImageDst() const;				// The result image, after computation

	int getBlockSizeHarris() const;
	void setBlockSizeHarris( int iBlockSize );
	int getMaskSizeHarris() const;
	void setMaskSizeHarris( int iMaskSize );
	float getKappaHarris() const;
	void setKappaHarris( float iKappa );
	int getMaxPixelValueHarris() const;
	void setMaxPixelValueHarris( int iMaxValue );
	int getNumFeaturePtsHarris() const;
	void setThresHarris( float fThres );
	float getThresHarris() const;

	int getMaskSizeNMS() const;
	void setMaskSizeNMS( int iMaskSize );

	int getConstLog() const;
	void setConstLog( int iConst );
	float getEpsLog() const;
	void setEpsLog( float fEps );

	int getThresLowCanny() const;
	void setThresLowCanny( int iThresLow );
	int getThresHighCanny() const;
	void setThresHighCanny( int iThresHigh );
	int getSobelMaskSizeCanny() const;
	void setSobelMaskSizeCanny( int iSobelMaskSize );

	int getSmoothTypeSmooth() const;
	void setSmoothTypeSmooth( int iSmoothType );
	int getSize1Smooth() const;
	void setSize1Smooth( int iSize1 );
	int getSize2Smooth() const;
	void setSize2Smooth( int iSize2 );
	double getSigma1Smooth() const;
	void setSigma1Smooth( double dSigma1 );
	double getSigma2Smooth() const;
	void setSigma2Smooth( double dSigma2 );

	int getEnclosureLevelHighlight() const;
	void setEnclosureLevelHighlight( int iEnclosureLevel );
	

private:
	IplImage* _pImageSrc;
	IplImage* _pImageDst;
	int _iNumRows;
	int _iNumCols;

	int _iBlockSizeHarris;
	int _iMaskSizeHarris;
	float _fKappaHarris;
	int _iMaxPixelValueHarris;
	float _fThresHarris;
	int _iNumFeaturePtsHarris;

	int _iMaskSizeNMS;

	int _iConstLog;
	float _fEpsLog;

	int _iThresLowCanny;
	int _iThresHighCanny;
	int _iSobelMaskSizeCanny;

	int _iSmoothTypeSmooth;
	int _iSize1Smooth;
	int _iSize2Smooth;
	double _dSigma1Smooth;
	double _dSigma2Smooth;

	int _iEnclosureLevelHighlight;

	void initializeImageDst( int iDepth );

};

#endif //IMAGEMANIP_H_